package net.lab1024.sa.admin.module.business.app.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.app.domain.RegisterForm;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.LoginForm;
import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.login.manager.LoginManager;
import net.lab1024.sa.admin.module.system.login.service.LoginService;
import net.lab1024.sa.admin.util.AdminRequestUtil;
import net.lab1024.sa.base.common.annoation.NoNeedLogin;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.constant.RequestHeaderConst;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.constant.LoginDeviceEnum;
import net.lab1024.sa.base.module.support.captcha.domain.CaptchaVO;
import net.lab1024.sa.base.module.support.loginlog.LoginLogResultEnum;
import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService;
import net.lab1024.sa.base.module.support.securityprotect.service.SecurityPasswordService;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;


@RestController
@Tag(name = AdminSwaggerTagConst.System.SYSTEM_LOGIN)
@RequestMapping("/api")
@Slf4j
public class APPLoginController {

    @Resource
    private LoginService loginService;
    @Resource
    private EmployeeService employeeService;
    @Resource
    private LoginManager loginManager;

    @NoNeedLogin
    @PostMapping("/login")
    @Operation(summary = "登录 ")
    public ResponseDTO<LoginResultVO> login(@Valid @RequestBody LoginForm loginForm, HttpServletRequest request) {
        String ip = JakartaServletUtil.getClientIP(request);
        String userAgent = JakartaServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT);
        return loginService.login(loginForm, ip, userAgent);
    }

    @NoNeedLogin
    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public ResponseDTO<LoginResultVO> register(@Valid @RequestBody RegisterForm registerForm, HttpServletRequest request) {
        String ip = JakartaServletUtil.getClientIP(request);
        String userAgent = JakartaServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT);

        // 1. 验证码校验
        ResponseDTO<String> captchaCheck = loginService.checkCaptcha(registerForm.getCaptchaKey(), registerForm.getCaptchaCode());
        if (!captchaCheck.getOk()) {
            return ResponseDTO.error(UserErrorCode.PARAM_ERROR,captchaCheck.getMsg());
        }

        // 2. 用户名存在性检查
        String username = registerForm.getUsername();
        EmployeeEntity existingUser = employeeService.getByLoginName(username);
        if (existingUser != null) {
            return ResponseDTO.userErrorParam("用户名已被占用");
        }

        // 3. 密码强度校验（示例：6-20位）
        String password = registerForm.getPassword();
        if (password.length() < 6 || (password.length() > 20)) {
            return ResponseDTO.userErrorParam("密码长度需为6-20位");
        }

        // 4. 邮箱格式校验（可选）
        String email = registerForm.getEmail();
        if (email != null && !email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")) {
            return ResponseDTO.userErrorParam("邮箱格式不正确");
        }

        // 5. 创建新用户实体
        EmployeeEntity newEmployee = new EmployeeEntity();
        newEmployee.setLoginName(username);
        newEmployee.setEmail(email);
        newEmployee.setLoginPwd(password);
        newEmployee.setDeletedFlag(false);
        newEmployee.setDisabledFlag(false);
        newEmployee.setCreateTime(LocalDateTime.now());
        newEmployee.setUpdateTime(LocalDateTime.now());

        // 6. 保存到数据库
        boolean saveResult = employeeService.save(newEmployee);
        if (!saveResult) {
            log.error("用户注册失败，无法保存到数据库：{}", username);
            return ResponseDTO.error(UserErrorCode.PARAM_ERROR,"注册失败，请稍后重试");
        }

        // 7. 自动登录新用户
        String saTokenLoginId = UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + newEmployee.getEmployeeId();
        StpUtil.login(saTokenLoginId);

        // 8. 生成登录结果
        RequestEmployee requestEmployee = loginManager.loadLoginInfo(newEmployee);
        String token = StpUtil.getTokenValue();
        LoginResultVO loginResultVO = loginService.getLoginResult(requestEmployee, token);
        loginResultVO.setToken(token);

        // 9. 记录注册日志
        loginService.saveLoginLog(newEmployee, ip, userAgent, "新用户注册", LoginLogResultEnum.LOGIN_SUCCESS, LoginDeviceEnum.ANDROID);

        return ResponseDTO.ok(loginResultVO);
    }


}
